/**
 * M1 MIAGE APP - INF1
 * Cédric Hulin
 * Julien Trébern
 */
package controlleur;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import jjgener.ParseException;
import jjgener.ProgArbre;
import progarbre.ASAProg;
import vue.InterpreteurView;

/**
 * Controlleur de l'interpreteur
 */
public class InterpreteurController implements ActionListener {

    /**
     * La vue
     */
    protected InterpreteurView view;
    private String filePath;

    /**
     * Constructeur normal.
     */
    public InterpreteurController(InterpreteurView view) {
        this.view = view;
        this.filePath = null;
    }

    /**
     * Implementation de la methode d'interception d'evenement.
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Charger")) {
            JFileChooser chooser = getFileChooser();

            if (chooser.showOpenDialog(view) != JFileChooser.APPROVE_OPTION) {
                return;
            }
            filePath = chooser.getSelectedFile().getAbsolutePath();
            view.setText(getContent(filePath));
            view.griserBoutons(false);
            view.setConsole("");
        }
        if (e.getActionCommand().equals("Sauvegarder vers") || e.getActionCommand().equals("Nouveau")) {
            SauvegarderSous();
        }
        if (e.getActionCommand().equals("Sauvegarder")) {
            Sauvegarder(false);
        }
        if (e.getActionCommand().equals("Exécuter")) {
            Sauvegarder(false);

            view.setConsole("");

            ProgArbre parser = null;
            ASAProg prog = null;
            try {
                parser = new ProgArbre(new FileInputStream(filePath));
            }
            catch (FileNotFoundException ex) {
                view.afficherErreur("File not found : " + filePath);
                return;
            }
            try {
                prog = parser.parse();
                prog.initialiser(view);
                prog.setView(view.console);
            }
            catch (RuntimeException ex) {
                view.afficherErreur("Erreur de compilation : " + ex.getMessage());
                return;
            }
            catch (ParseException ex) {
                view.afficherErreur("Erreur de compilation : " + ex);
                Logger.getLogger(InterpreteurController.class.getName()).log(Level.SEVERE, null, ex);
                return;
            }

            try {
                prog.executer();
            }
            catch (RuntimeException ex) {
                view.afficherErreur("Problème durant l'éxecution : " + ex.getMessage());
            }
            catch (Exception ex) {
                view.afficherErreur("Problème d'execution : " + ex);
                Logger.getLogger(InterpreteurController.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        if (e.getActionCommand().equals("Notation explorateur")) {
            view.setConsole("");

            ProgArbre parser = null;
            ASAProg prog = null;
            try {
                parser = new ProgArbre(new FileInputStream(filePath));
            }
            catch (FileNotFoundException ex) {
                view.afficherErreur("File not found : " + filePath);
                return;
            }
            try {
                prog = parser.parse();
                view.setConsole(prog.notationExplorateur());
            }
            catch (ParseException ex) {
                view.afficherErreur("Erreur de compilation" + ex);
                Logger.getLogger(InterpreteurController.class.getName()).log(Level.SEVERE, null, ex);
                return;
            }
        }

    }

    private JFileChooser getFileChooser() {
        JFileChooser chooser = new JFileChooser(new File("."));
        ExampleFileFilter filter = new ExampleFileFilter();
        filter.addExtension("picol");
        filter.setDescription("Fichier PicoL");
        chooser.setFileFilter(filter);
        return chooser;
    }

    private void SauvegarderSous() {
        JFileChooser chooser = getFileChooser();

        if (chooser.showSaveDialog(view) != JFileChooser.APPROVE_OPTION) {
            return;
        }

        if (chooser.getSelectedFile() == null) {
            return;
        }

        File fileToSave = chooser.getSelectedFile();
        if (!fileToSave.getName().contains(".picol")) {
            fileToSave = new File(fileToSave.getAbsoluteFile() + ".picol");
        }

        filePath = fileToSave.getAbsolutePath();
        Sauvegarder(true);
        view.griserBoutons(false);
    }

    private void Sauvegarder(boolean withConfirmation) {
        if (filePath == null) {
            return;
        }

        File fileToSave = new File(filePath);
        if (!fileToSave.getName().contains(".picol")) {
            fileToSave = new File(fileToSave.getAbsoluteFile() + ".picol");
        }


        if (withConfirmation) {
            if (fileToSave.exists()) {
                if (!view.demanderConfirmation("Voulez-vous ecraser le fichier existant ?")) {
                    return;
                }
                fileToSave.delete();
            }
        }
        else if (fileToSave.exists()) {
            fileToSave.delete();
        }

        try {
            fileToSave.createNewFile();
            Charset charset = Charset.forName("UTF-8");
            Writer writer = new OutputStreamWriter(new FileOutputStream(fileToSave), charset);
            try {
                writer.append(view.getText());
            }
            finally {
                writer.close();
            }
        }
        catch (IOException ex) {
            Logger.getLogger(InterpreteurController.class.getName()).log(Level.SEVERE, null, ex);
        }

        filePath = fileToSave.getAbsolutePath();
        view.setConsole(filePath);
    }

    private String getContent(String fichier) {
        String chaine = "";
        if (fichier == null) {
            return chaine;
        }
        try {
            InputStream ips = new FileInputStream(fichier);
            InputStreamReader ipsr = new InputStreamReader(ips);
            BufferedReader br = new BufferedReader(ipsr);
            String ligne;
            while ((ligne = br.readLine()) != null) {
                chaine += ligne + "\n";
            }
            br.close();
        }
        catch (Exception e) {
            view.afficherErreur("Chemin de fichier invalide");
        }
        return chaine;
    }
}
